#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <fcgi_stdio.h>

#include "cfg.h"
#include "cJSON.h"
#include "mysql_conn.h"
#include "make_log.h"
#include "utils.h"

static char mysql_user[128] = {0};
static char mysql_pwd[128] = {0};
static char mysql_db[128] = {0};

int get_md5_info(char* buf, char* user, char* token, char* md5, char* filename);
int deal_md5(char* user, char* md5, char* filename);

int main()
{

    read_cfg(mysql_user, mysql_pwd, mysql_db);

    while(FCGI_Accept() >= 0)
    {
        char* contentLength = getenv("CONTENT_LENGTH");
        int len;

        printf("Content-type: text/html; charset=utf8\r\n\r\n");

        if(contentLength == NULL)
        {
            len = 0;
        }
        else
        {
            len = atoi(contentLength);
        }

        if(len <= 0)
        {
            printf("No data from standard input.<p>\n");
            LOG("len = 0, No data from standard input");
        }
        else
        {
            char buf[4*1024] = {0};
            int ret = 0;
            ret = fread(buf, 1, len, stdin);

            if(ret == 0)
            {
                LOG("fread() error!\n");
                continue;
            }

            LOG("buf = %s\n", buf);

            //解析json中信息
            /*
            * {
                user:xxxx,
                token: xxxx,
                md5:xxx,
                fileName: xxx
                }
            */
            char user[128] = {0};
            char md5[128] = {0};
            char token[256] = {0};
            char filename[128] = {0};
            ret = get_md5_info(buf, user, token, md5, filename);
            if(ret != 0)
            {
                LOG("get_md5_info() error!\n");
                continue;
            }

            LOG("user=%s, token=%s, md5=%s, filename=%s\n", user, token, md5, filename);
            ret = verify_token(user, token);
            if(ret == 0)
            {
                LOG("用户验证成功！");
                deal_md5(user, md5, filename);
            }
            else
            {
                char* out = return_status("111");
                if(out != NULL)
                {
                    printf(out);
                    free(out);
                }
            }
        }
    }
    return 0;
}

int get_md5_info(char* buf, char* user, char* token, char* md5, char* filename)
{
    int ret = 0;

    cJSON* root = NULL;
    do
    {
        root = cJSON_Parse(buf);
        if(root == NULL)
        {
            LOG("cJSON_Parse() error\n");
            ret = -1;
            break;
        }

        cJSON* user_js = cJSON_GetObjectItem(root, "user");
        if(user_js == NULL)
        {
            LOG("cJSON_GetObjectItem() error\n");
            ret = -1;
            break;
        }

        cJSON* md5_js = cJSON_GetObjectItem(root, "md5");
        if(md5_js == NULL)
        {
            LOG("cJSON_GetObjectItem() error\n");
            ret = -1;
            break;
        }

        cJSON* token_js = cJSON_GetObjectItem(root, "token");
        if(token_js == NULL)
        {
            LOG("cJSON_GetObjectItem() error\n");
            ret = -1;
            break;
        }

        cJSON* filename_js = cJSON_GetObjectItem(root, "fileName");
        if(filename_js == NULL)
        {
            LOG("cJSON_GetObjectItem() error\n");
            ret = -1;
            break;
        }

        strcpy(user, user_js->valuestring);
        strcpy(token, token_js->valuestring);
        strcpy(md5, md5_js->valuestring);
        strcpy(filename, filename_js->valuestring);
    }while(0);

    if(root != NULL)
    {
        cJSON_Delete(root);
        root = NULL;
    }

    return ret;
}

//秒传处理
//返回值：0秒传成功，-1出错，-2此用户已拥有此文件， -3秒传失败
int deal_md5(char* user, char* md5, char* filename)
{
    int ret = 0;

    MYSQL* conn = NULL;
    int ret2 = 0;
    char tmp[512] = {0};
    char sql_cmd[512] = {0};
    char* out = NULL;

    do
    {
        conn = get_mysql(mysql_user, mysql_pwd, mysql_db);
        if(conn == NULL)
        {
            LOG("get_mysql() error\n");
            ret = -1;
            break;
        }

        //sql 语句，获取此md5值文件的文件计数器 count
        sprintf(sql_cmd, "select count from file_info where md5='%s'", md5);
        ret2 = process_result_one(conn, sql_cmd, tmp);
        if(ret2 == 0)
        {
            int count = atoi(tmp);
            sprintf(sql_cmd, "select * from user_file_list where user='%s' and md5='%s' and file_name='%s'", user, md5, filename);

            //返回值： 0成功并保存记录集，1没有记录集，2有记录集但是没有保存，-1失败
            ret2 = process_result_one(conn, sql_cmd, NULL);
            if(ret2 == 2)
            {
                LOG("%s[filename:%s, md5:%s]已存在\n", user, filename, md5);
                ret = -2;
                break;
            }

            sprintf(sql_cmd, "update file_info set count = %d where md5 = '%s'", ++count, md5);
            if(mysql_query(conn, sql_cmd) != 0)
            {
                LOG("%s操作失败: %s\n", sql_cmd, mysql_error(conn));
                ret = -1;
                break;
            }

            struct timeval tv;
            struct tm* ptm;
            char time_str[128] = {0};

            gettimeofday(&tv, NULL);
            ptm = localtime(&tv.tv_sec);
            strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", ptm);

            sprintf(sql_cmd, "insert into user_file_list(user, md5, create_time, file_name, shared_status, pv) values('%s', '%s', '%s', '%s', %d, %d)", user, md5, time_str, filename, 0, 0);
            if(mysql_query(conn, sql_cmd) != 0)
            {
                LOG("%s操作失败：%s\n", sql_cmd, mysql_error(conn));
                ret = -1;
                break;
            }

            sprintf(sql_cmd, "select count from user_file_count where user = '%s'", user);
            count = 0;

            ret2 = process_result_one(conn, sql_cmd, tmp);
            if(ret2 == 1)
            {
                sprintf(sql_cmd, "insert into user_file_count(user, count) values('%s', %d)", user, 1);
            }
            else
            {
                count = atoi(tmp);
                sprintf(sql_cmd, "update user_file_count set count = %d where user = '%s'", count+1, user);
            }

            if(mysql_query(conn, sql_cmd) != 0)
            {
                LOG("%s操作失败：%s\n", sql_cmd, mysql_error(conn));
                ret = -1;
                break;
            }
        }
        else if(1 == ret2)//没有结果，秒传失败
        {
            ret = -3;//0秒传成功，-1出错，-2此用户已拥有此文件， -3秒传失败
            break;
        }
    }while(0);

    //ret的值：0秒传成功，-1出错，-2此用户已拥有此文件， -3秒传失败
    /*
    秒传文件：
        文件已存在：{"code":"005"}
        秒传成功：  {"code":"006"}
        秒传失败：  {"code":"007"}
    */

    if(ret == 0)
    {
        out = return_status("006");
    }
    else if(ret == -2)
    {
        out = return_status("005");
    }
    else
    {
        out = return_status("007");
    }

    if(out != NULL)
    {
        printf(out);
        free(out);
    }

    if(conn != NULL)
    {
        mysql_close(conn);
    }

    return ret;
}